MongoDB 副本集与分片
MongoDB 系统讲解第二篇:02 篇理论篇讲过集群的概念轮廓,这一篇落到机制——oplog、选举、读偏好与写关注,以及分片架构里最重要的"片键怎么选"。
副本集:三种角色
Primary(主) —— 所有写请求的入口
Secondary(从) —— 复制主的数据,可分担读;主挂了参与竞选
Arbiter(仲裁) —— 只有投票权没有数据,省资源凑奇数票(书里评价:能用真从库就别用仲裁者)
oplog 是复制的核心:主库的每个写操作记进一个固定大小的环形集合(local.oplog.rs),从库拉取并幂等地重放。固定大小意味着写太猛会把旧 oplog 冲掉——从库同步不上来就退回全量初始同步,生产要监控 oplog 窗口。
选举:主不可达时,有投票权的成员选出新主(类 Raft)。要点:
- 投票成员数奇数(3 / 5 / 7)
priority高的从库优先当选(可指定某台机器当主)- 大多数派存活才选得出主——两台机器坏一台和坏一半不一样,这就是为什么副本集最少 3 个数据节点
读写关注:一致性旋钮
readPreference(读走哪个节点):
| 模式 | 读谁 | 场景 |
|---|---|---|
| primary(默认) | 只读主 | 强一致读 |
| primaryPreferred | 主优先,主挂读从 | 高可用兜底 |
| secondary | 只读从 | 分析类查询,容忍旧数据 |
| secondaryPreferred | 从优先 | 读写分离典型选择 |
| nearest | 最近的 | 多地域部署 |
writeConcern(写确认级别):w: 1 主确认就返回(快,可能丢);w: "majority" 多数派确认(安全,慢一点);配 j: true 再加日志落盘确认。读级别和写级别的组合就是一致性与延迟的旋钮——这是副本集篇最核心的一句话。
分片架构:三个角色
mongos(路由) —— 应用连它,按片键把请求路由到对应分片
config server —— 存元数据:哪些数据在哪个分片(路由表)
shard —— 每个分片本身就是一个副本集(高可用是分片的前提)
片键:分片里最重要的决定
片键(shard key)决定数据怎么分布,选了之后改起来要重建集合(除非在线 refine,且限制很多):
| 片键类型 | 分布 | 优点 | 缺点 |
|---|---|---|---|
| 范围片键(如 userId 区间) | 相邻数据同分片 | 范围查询高效 | 单调递增键(时间戳)全写进最后一片=热点 |
| 哈希片键 | 均匀打散 | 写入均匀 | 范围查询变广播 |
| 复合片键 | 组合 | 兼顾 | 设计复杂 |
片键三条红线(书里反复强调):
- 基数要高(低基数字段,比如"性别",分不出几片)
- 别用单调递增的值做范围片键(追加写入全打到最后一片)
- 查询要带上片键(不带片键的查询变成"扇出到所有分片"的散射查询)
chunk 与均衡:数据按片键切成 chunk(块),balancer 后台在各分片间搬 chunk 保持均衡;搬不动的超大块叫 jumbo chunk(片键选择不当的产物)。
💡 我的记忆锚点:副本集解决"高可用 + 读扩展",分片解决"写与数据量"——先副本集,真到瓶颈再分片;分片的第一道坎不是运维,是片键设计。MongoDB 8.0 前后版本的分片机制一直在演进(config server 主从等),动手前查当时官方文档。
💬 评论